package com.c2b.algorithm.leetcode.base;

/**
 * <a href='https://leetcode.cn/problems/shortest-completing-word/'>最短补全词(Shortest Completing Word)</a>
 * <p>给你一个字符串 licensePlate 和一个字符串数组 words ，请你找出 words 中的 最短补全词 。</p>
 * <p>补全词 是一个包含 licensePlate 中所有字母的单词。忽略 licensePlate 中的 数字和空格 。不区分大小写。如果某个字母在 licensePlate 中出现不止一次，那么该字母在补全词中的出现次数应当一致或者更多。</p>
 * <p>例如：licensePlate = "aBc 12c"，那么它的补全词应当包含字母 'a'、'b' （忽略大写）和两个 'c' 。可能的 补全词 有 "abccdef"、"caaacab" 以及 "cbca" 。</p>
 * <p>请返回 words 中的 最短补全词 。题目数据保证一定存在一个最短补全词。当有多个单词都符合最短补全词的匹配条件时取 words 中 第一个 出现的那个。</p>
 *
 * <p>
 * <b>示例：</b>
 * <pre>
 * 示例 1：
 *      输入：licensePlate = "1s3 PSt", words = ["step", "steps", "stripe", "stepple"]
 *      输出："steps"
 *      解释：最短补全词应该包括 "s"、"p"、"s"（忽略大小写） 以及 "t"。
 *          "step" 包含 "t"、"p"，但只包含一个 "s"，所以它不符合条件。
 *          "steps" 包含 "t"、"p" 和两个 "s"。
 *          "stripe" 缺一个 "s"。
 *          "stepple" 缺一个 "s"。
 *          因此，"steps" 是唯一一个包含所有字母的单词，也是本例的答案。
 *
 * 示例 2：
 *      输入：licensePlate = "1s3 456", words = ["looks", "pest", "stew", "show"]
 *      输出："pest"
 *      解释：licensePlate 只包含字母 "s" 。所有的单词都包含字母 "s" ，其中 "pest"、"stew"、和 "show" 三者最短。答案是 "pest" ，因为它是三个单词中在 words 里最靠前的那个。
 * </pre>
 * </p>
 *
 * <p>
 * <b>提示：</b>
 * <ul>
 *     <li>1 <= licensePlate.length <= 7</li>
 *     <li>licensePlate 由数字、大小写字母或空格 ' ' 组成</li>
 *     <li>1 <= words.length <= 1000</li>
 * </ul>
 * </p>
 *
 * @author c2b
 * @since 2024/1/12 10:36
 */
public class LC0748ShortestCompletingWord_S {

    static class Solution {
        public String shortestCompletingWord(String licensePlate, String[] words) {
            int[] cnt = getCnt(licensePlate);
            String ans = null;
            for (String s : words) {
                int[] cur = getCnt(s);
                // 假设当前字符满足条件
                boolean ok = true;
                for (int i = 0; i < 26; i++) {
                    // 如果不满足直接跳出，判断下一个
                    if (cnt[i] > cur[i]) {
                        ok = false;
                        break;
                    }
                }
                // 如果满足更新结果
                if (ok && (ans == null || ans.length() > s.length())) {
                    ans = s;
                }
            }
            return ans;
        }

        private int[] getCnt(String s) {
            int[] cnt = new int[26];
            for (char c : s.toCharArray()) {
                if (Character.isLetter(c)) cnt[Character.toLowerCase(c) - 'a']++;
            }
            return cnt;
        }
    }
}
